﻿using CSRedis;
using Microsoft.Extensions.Caching.Memory;
using WH.Common.Enums;
using WH.Common.Config;
using WH.Common.Config.Options;
using Rw.Core.Redis;
using WH.Common.Cache;
using Autofac;
using System;
using RedisOptions = WH.Common.Config.Options.RedisOptions;

namespace WH.Extensions.Setup
{
    public class AutofacCachingSetup : Autofac.Module
    {

        private readonly CacheOpttions _cacheOptions;
        private readonly RedisOptions _redisOptions;

        public AutofacCachingSetup(IConfigurationCenter configurationCenter)
        {
            _cacheOptions = configurationCenter.CacheOpttions;
            _redisOptions = configurationCenter.RedisOptions;


            _cacheInstace = null;
        }
        protected override void Load(ContainerBuilder builder)
        {

            bool enable = _cacheOptions.Enable;
            CacheModeEnum cacheMode = _cacheOptions.Mode;

            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            ////services.AddMemoryCache();
            //services.AddSingleton<IMemoryCache>(factory =>
            //{
            //    return memoryCache;
            //});

            builder.RegisterInstance(memoryCache).As<IMemoryCache>().SingleInstance();
            builder.RegisterType<MemoryCaching>().As<ICaching>().SingleInstance();


            if (enable)
            {
                if (cacheMode == CacheModeEnum.Redis)
                {
                    if (_redisOptions == null)
                    {
                        throw new ArgumentException("请检查RedisOptions配置是否添加");
                    }

                    var redis = new CSRedisClient($"{_redisOptions.Default.Server}:{_redisOptions.Default.Port},password={_redisOptions.Default.Password},defaultDatabase={_redisOptions.Default.DefaultDatabase}");
                    
                    try
                    {
                        if (redis.Ping())
                        {
                            builder.RegisterInstance(redis).SingleInstance();

                            builder.RegisterType<RedisService>().As<IRedisService>().SingleInstance();

                            builder.RegisterType<RedisCaching>().As<ICaching>().SingleInstance().AsImplementedInterfaces();
                        }
                    }
                    catch (Exception ex)
                    {
                        redis.Dispose();
                    }
                }
            }
        }

        private static readonly object _Object = new object();
        private static IMemoryCache? _cacheInstace = null;

        private static IMemoryCache memoryCache
        {
            get
            {
                if (_cacheInstace == null)
                {
                    lock (_Object)
                    {
                        if (_cacheInstace == null)
                        {
                            _cacheInstace = new MemoryCache(new MemoryCacheOptions());
                        }
                    }
                }
                return _cacheInstace;
            }
        }

    }
}
